#!/usr/bin/env python
#coding=utf-8
#system default setting
import PUBLICMETHOD
import sys
import os
import linecache
import threading

from operator import attrgetter



#system default setting
reload(sys)
sys.setdefaultencoding('utf-8')


#Tag
#########################################################################################################
#store the data of each tag
class Tag:

	def __init__(self, tagId, tagName, tagTypeId, tagFullId, tagOntologyId):
		self.tagId = tagId
		self.tagName = tagName
		self.tagTypeId = tagTypeId
		self.tagFullId = tagFullId
		self.OntologyId = tagOntologyId
		self.tagWei = 0.0
		self.tagTotalWordNum = tagName.count(" ") + 1
		self.tagTotalAlphNum = len(tagName) - self.tagName.count(" ")
		self.tagMatchedWordPercent = 0.0
		self.tagMatchedAlphPercent = 0.0
		
	def setTagWei(self, tagWei):
		self.tagWei = tagWei

	def setTagMatchedWordPercent(self, matchedWordNum):
		self.tagMatchedWordPercent = float(matchedWordNum) / float(self.tagTotalWordNum)

	def setTagMatchedAlphPercent(self, matchedAlphNum):
		self.tagMatchedAlphPercent = float(matchedAlphNum) / float(self.tagTotalAlphNum)

	def getTagMatchedAlphPercent(self):
		return self.tagMatchedAlphPercent

	def getTagMatchedWordPercent(self):
		return self.tagMatchedWordPercent

	def getTagWei(self):
		return self.tagWei

	def getTagId(self):
		return self.tagId

	def getTagName(self):
		return self.tagName

	def getTagTypeId(self):
		return self.tagTypeId

	def getTagFullId(self):
		return self.tagFullId

	def getOntologyId(self):
		return self.OntologyId

	def getTagTotalWordNum(self):
		return self.tagTotalWordNum

	def getTagTotalAlphNum(self):
		return self.tagTotalAlphNum
"""
class Ontology:

	def __init__(self):
		self.__ontologyId = self.__ontologyName = ""

	def getOntologyId(self):
		return self.__ontologyId

	def getOntologyName(self):
		return self.__ontologyName
"""

class ShowedTag:
	def __init__(self):
		self.__tagId = self.__tagName = self.__ontologyName = ""

	def getShowedTag(self, ontologyDic, tag):
		self.__tagScore = tag.getTagWei()
		self.__tagId = tag.getTagId()
		self.__tagName = tag.getTagName()
		#print "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
		#print self.__tagName
		dicIndex = str(tag.getOntologyId())
		#print dicIndex
		self.__ontologyLink = ontologyDic[dicIndex][0]
		self.__ontologyName = ontologyDic[dicIndex][1]
		#print self.__ontologyName
		return self

	def getShowedTagScore(self):
		return str(self.__tagScore)

	def getOntologyLink(self):
		return self.__ontologyLink

	def getShowedTagId(self):
		return self.__tagId

	def getShowedTagName(self):
		return self.__tagName

	def getOntologyName(self):
		return self.__ontologyName

class TagInform:
	def __init__(self):
		self.__matchedTagList = []
		self.__showedTagList = []

	def sortMatchedTagList(self):
		#sortedByWordWei, matchedTagWordPercent, matchedTagAlphPercent
		self.__matchedTagList = sorted(self.__matchedTagList, key = attrgetter("tagWei", "tagMatchedWordPercent","tagMatchedAlphPercent"), reverse=True)

	def filteredMatchedTagList(self, length):
		i = 0
		while i < len(self.__matchedTagList):
			"""
			print tagInform.getTagId()
			print tagInform.getTagName()
			print tagInform.getTagTotalAlphNum()
			"""
			if self.__matchedTagList[i].getTagTotalAlphNum() > length:
				"""
				pause = raw_input("pause2")
				print self.__matchedTagList[i].getTagId()
				"""
				del self.__matchedTagList[i]
				i -= 1
			i += 1

	def constructAndGainMatchedTagList(self, matchedTagWordInformList, TagDATPath, filteredTagList):

		"""
		for tagIndex in tagIndexList:
			print tagIndex.getTagName()
			print tagIndex.getTagIndex()
		"""
		#use global thread lock
		mylock = threading.RLock()
		mylock.acquire()

		#print TagDATPath
		for tagWordInform in matchedTagWordInformList:
			tagContent = linecache.getline(TagDATPath, tagWordInform.getMatchedTagWordSeqNo() + 1)
			tagWei = tagWordInform.getMatchedTagWordWei()
			matchedTagAlphNum = tagWordInform.getMatchedTagWordAlphNum()
			matchedTagWordNum = tagWordInform.getMatchedTagWordNum()
			#print "****************************"
			#print tagIndex.getTagIndex() + 1
			#print tagContent
			#print "****************************"

			#delete "\n" which is in the end of tagContent
			tagContent = tagContent[:-1]
			#print tagContent
			tagData = tagContent.split("\t")

			#print tagData[4]
			#print tagData

			"""
			i = 0
			while i < 5:
				print str(i) + "=" + tagData[i]
				i += 1
			"""
			try:
				#filter by ontologies
				for filteredTag in filteredTagList:
					if filteredTag == "all" or filteredTag == tagData[4]:
						tag = Tag(tagData[0], tagData[1], tagData[2], tagData[3], tagData[4])
						tag.setTagWei(tagWei)
						tag.setTagMatchedWordPercent(matchedTagWordNum)
						tag.setTagMatchedAlphPercent(matchedTagAlphNum)
						self.__matchedTagList.append(tag)
			except Exception, ex:
				#print ex
				print "the TAG DAT files is illegal"
			
		mylock.release()

		#sort
 		self.sortMatchedTagList()

 		#filter length of tag's name
 		self.filteredMatchedTagList(20)

		return self.__matchedTagList


	def constructShowedTagList(self, ontologyDic):
		"""
		i = 1
		while i <= 15:
			print ontologyDic[i]
			i += 1
		"""
		
		"""
		for tag in self.__matchedTagList:
			print tag.getOntologyId()
		"""
		try:
			#i = 0
			for tag in self.__matchedTagList:
				showedTag = ShowedTag()
				self.__showedTagList.append(showedTag.getShowedTag(ontologyDic, tag))
				#print id(temp)
				#print id(self.__showedTagList)
				#print self.__showedTagList[i].getShowedTagId()
				#print self.__showedTagList[i].getShowedTagName()
				#print self.__showedTagList[i].getOntologyName()
				#i += 1
			#for tag in self.__showedTagList:
				#print id(tag)
				#print tag.getShowedTagId()
				#print tag.getShowedTagName()
				#print tag.getOntologyName()
		except Exception, ex:
			#print ex
			print "The Ontology Id is illegal"

		"""
		for tag in self.__showedTagList:	
			print tag.getShowedTagId()
			print tag.getShowedTagName()
			print tag.getOntologyName()
		i += 1
		"""
		#print self.__showedTagList.__len__()
		return self.__showedTagList
		

		
"""
class TagWordSeqNo:
	#__slots__ = ('__wordSeqNoList', '__wordName')

	def __init__(self, wordName):
		self.__wordSeqNoList = []
		self.__wordName = wordName

	def addWordSeqNo(self, tagSeqNo):
		self.__wordSeqNoList.append(tagSeqNo)

	def getWordSeqNoList(self):
		return self.__wordSeqNoList

	def getWordName(self):
		return self.__wordName
"""

#use a tag as an unit
class MatchedTagWordInform:
	def __init__(self, tagWordSeqNo, wordWei, alphNum):
		self.__matchedTagWordSeqNo = tagWordSeqNo
		self.__matchedTagWordWei = wordWei
		self.__matchedTagWordAlphNum = alphNum
		self.__matchedTagWordNum = 1

	def addMatchedSameTagWordWei(self, wordWei, alphNum):
		self.__matchedTagWordWei += wordWei
		self.__matchedTagWordAlphNum += alphNum
		self.__matchedTagWordNum += 1

	def getMatchedTagWordNum(self):
		return self.__matchedTagWordNum

	def getMatchedTagWordAlphNum(self):
		return self.__matchedTagWordAlphNum

	def getMatchedTagWordWei(self):
		return self.__matchedTagWordWei

	def getMatchedTagWordSeqNo(self):
		return self.__matchedTagWordSeqNo

class MatchedTagWordInformList:
	def __init__(self):
		self.__matchedTagWordInformList = []

	def addMatchedTagWordInform(self, tagWordSeqNoList, wordWei, alphNum):
		for tagWordSeqNo in tagWordSeqNoList:
			isMatched = False
			for matchedTagWordInform in self.__matchedTagWordInformList:
				if matchedTagWordInform.getMatchedTagWordSeqNo() == tagWordSeqNo:
					isMatched = True
					matchedTagWordInform.addMatchedSameTagWordWei(wordWei, alphNum)
					break
			if isMatched == False:
				matchedTagWordInform =  MatchedTagWordInform(tagWordSeqNo, wordWei, alphNum)
				self.__matchedTagWordInformList.append(matchedTagWordInform)


	def constructMatchedTagWordInformList(self, tagWordSeqNoList, wordWei, alphNum):
		for tagWordSeqNo in tagWordSeqNoList:
			matchedTagWordInform =  MatchedTagWordInform(tagWordSeqNo, wordWei, alphNum)
			self.__matchedTagWordInformList.append(matchedTagWordInform)

	def getMatchedTagWordInformList(self):
		return self.__matchedTagWordInformList

	def getMatchedTagWordInformListLen(self):
		return len(self.__matchedTagWordInformList)

	def getMatchedTagWordWeiList(self):
		weiList = []
		for data in self.__matchedTagWordInformList:
			weiList.append(data.getMatchedTagWordWei())
		return weiList


class TagWordSeqNoDic:

	def __init__(self):
		self.__tagWordSeqNoDic = {}

	#use dic to store the DAT file
	def addTagWordSeqNo(self, tagNameWord, tagSeqNo):
		#formation
		tagNameWord = str(tagNameWord)
		tagSeqNo = int(tagSeqNo)
		if self.__tagWordSeqNoDic == {}:	
			tagSeqNoList = [tagSeqNo]
			self.__tagWordSeqNoDic[tagNameWord] = tagSeqNoList
		else:
			#if the tagWordWord is exist, put the index into tagWordSeqNoList of that word
			if tagNameWord in self.__tagWordSeqNoDic:	
				seqNoList = self.__tagWordSeqNoDic[tagNameWord]
				seqNoList.append(tagSeqNo)
				self.__tagWordSeqNoDic[tagNameWord]  = seqNoList
			#if the tagWordSeqNo isn't exist, construct a new tagWordSeqNo	
			else :
				#print "!="
				tagSeqNoList = [tagSeqNo]
				self.__tagWordSeqNoDic[tagNameWord] = tagSeqNoList
			##test code##
			"""
			for data in self.__tagWordSeqNoDic:
				print data
				print self.__tagWordSeqNoDic[data]
			"""
			###pause code##
			"""
			pause = raw_input("pause")
			"""


	def readDAT(self, TagDATPath):
		tagSeqNo = 0
		lineContent = PUBLICMETHOD.ReadFile.readDAT(TagDATPath)
		isFirstLine = True
		#print sys.getsizeof(lineContent)
		for line in lineContent:
			if isFirstLine == True:
				isFirstLine = False
			else:
				tagData = line.split('\t')
				tagNameContent = tagData[1].split()
				for tagNameWord in tagNameContent:
					self.addTagWordSeqNo(tagNameWord, tagSeqNo)
				del tagData
				del tagNameContent
			tagSeqNo += 1
		#print id(tagDataList)
		del lineContent
		PUBLICMETHOD.ReadFile.closeFile()
		#print len(self.__tagWordSeqNoDic)
		#print sys.getsizeof(self.__tagWordSeqNoDic)

	def getTagWordSeqNoDic(self):
		return self.__tagWordSeqNoDic






#########################################################################################################